import GameConfig from "../GameConfig";
import UILangData, { SimpleLangData } from "../NRLib/base/UILangData";
import AudioExt from "../NRLib/ccExt/AudioExt";

const { ccclass, property, menu } = cc._decorator;

/**
 * 直接挂载在游戏场景上即可
 */
@ccclass
@menu('GlobalUI/CloseTimerTips')
export default class CloseTimerTips extends cc.Component {

	// 背景遮罩(遮罩透明度统一+增加淡入淡出动画)
	@property(cc.Node)
	private readonly blackMask: cc.Node = null;
	@property(cc.Animation)
	private readonly anim: cc.Animation = null;

	// 消息框标题
	@property(cc.Label)
	private readonly title: cc.Label = null;
	// 消息框内容
	@property(cc.Label)
	private readonly messageFull: cc.Label = null;

	// 单按钮（ok按钮）
	@property(cc.Node)
	private readonly btnOK: cc.Node = null;
	@property(cc.Label)
	private readonly tipsOk: cc.Label = null;

	// 短提示
	@property(cc.Label)
	private readonly messageShort: cc.Label = null;
	@property(cc.Node)
	private readonly shortUI: cc.Node = null;


	// 消息框多语言信息
	private _langData: UILangData = null;
	// UI正在动画中
	private isAnimating: boolean = false;
	// 倒计时秒数
	private _sec: number = 0;
	/** 获取特定格式时间字符串--00:00 */
	private get secStr(): string {
		const min = Math.floor(this._sec / 60);
		const minStr = ('0' + min).slice(-2);
		const sec = Math.round(this._sec - min * 60);
		const secStr = ('0' + sec).slice(-2);
		return minStr + ':' + secStr;
	}


	protected onLoad(): void {
		if (CC_PREVIEW)
			globalThis.CloseTips = this;
		this.initLangData();
		this.btnOK.getComponent(cc.Button).enableAutoGrayEffect = false;
		this.node.active = true;
		this.shortUIActive = false;
		this.dialogActive = false;
		// 监听关服事件
		yy.event.on(this, yy.event.room.RoomWillClose, this.onRoomWillClose);
	}

	protected onDestroy(): void {
		this.unscheduleAllCallbacks();
		this.closeTimer();
	}

	private onRoomWillClose(e: yy.event.room.RoomWillClose) {
		this._sec = e.leftSeconds;
		// 约定60秒以内的关服当做立即关服，不做即将关闭提示
		if (this._sec < 60) {
			this._sec = 0;
			return;
		}
		this.startTimer();
		// 收到通知，弹出框UI
		this.showDialog();
	}

	private startTimer() {
		if (this._timerID >= 0) return;
		this._timerID = window.setInterval(() => {
			this._sec -= 1;
			if (this._sec <= 0) {
				this.closeTimer();
				this.scheduleOnce(() => {
					this.dialogActive = false;
					this.shortUIActive = true;
				}, 1);
			}
			this.resetDialog();
			this.resetTips();
		}, 1000);
	}
	private closeTimer() {
		if (this._timerID >= 0) {
			window.clearInterval(this._timerID);
			this._timerID = -1;
		}
	}
	private _timerID = -1;

	private showDialog() {
		if (this.isAnimating) return;
		AudioExt.playEffect('MenuShow');
		this.isAnimating = true;
		this.btnOK.getComponent(cc.Button).interactable = true;
		this.resetDialog();
		this.shortUI.active = false;
		// animation
		this.anim.node.opacity = 0;
		this.blackMask.opacity = 0;
		this.dialogActive = true;
		this.anim.play("kuangYS");
		this.anim.on('finished', this.onShowCompleted, this);
		// 背景遮罩动画
		this.blackMask.stopAllActions();
		cc.tween(this.blackMask)
			.to(0.21, { opacity: 220 })
			.start();
	}
	private onShowCompleted() {
		this.isAnimating = false;
		this.anim.off('finished', this.onShowCompleted, this);
	}
	private hideDialog() {
		if (this.isAnimating) return;
		AudioExt.playEffect('MenuClose');
		this.isAnimating = true;
		this.btnOK.getComponent(cc.Button).interactable = false;
		// animation
		this.anim.play("kuangYSshou");
		this.anim.on('finished', this.onHideCompleted, this);
		// 背景遮罩动画
		this.blackMask.stopAllActions();
		cc.tween(this.blackMask)
			.to(0.21, { opacity: 0 })
			.start();
	}
	private onHideCompleted() {
		this.isAnimating = false;
		this.anim.off('finished', this.onHideCompleted, this);
		this.dialogActive = false;
		this.resetTips();
		this.shortUI.active = true;
	}

	private set shortUIActive(b: boolean) {
		this.shortUI.active = b;
	}
	private get shortUIActive(): boolean {
		return this.shortUI.active;
	}
	private set dialogActive(b: boolean) {
		this.blackMask.active = b;
		this.anim.node.active = b;
	}
	private get dialogActive(): boolean {
		return this.blackMask.active;
	}

	private initLangData() {
		this._langData = new UILangData(GameConfig.langList, 'en');
		const json: SimpleLangData = {
			"msgtitle": {
				"en": "System Message",
				"zh": "系统消息",
				"zhf": "系統消息",
				"jp": "システムメッセージ",
				"id": "Pesan Sistem",
				"hi": "सिस्टम संदेश",
				"pt": "Mensagem do Sistema",
				"es": "Mensaje del Sistema",
				"ru": "Системное сообщение",
				"ar": "رسالة النظام",
				"ms": "Mesej Sistem",
				"my": "စနစ် မက်ဆေ့ဂျ်",
				"th": "ข้อความระบบ",
				"vi": "Thông tin hệ thống"
			},
			"confirm": {
				"en": "Confirm",
				"zh": "确定",
				"zhf": "確定",
				"jp": "確認",
				"id": "Konfirmasi",
				"hi": "पुष्टि करें",
				"pt": "Confirmar",
				"es": "Confirmar",
				"ru": "Подтвердить",
				"ar": "تأكيد",
				"ms": "Sahkan",
				"my": "အတည်ပြုရန်",
				"th": "ยืนยัน",
				"vi": "Xác nhận."
			},
			"shortTips": {
				"en": "Close after {&0}",
				"zh": "{&0}后关闭",
				"zhf": "{&0}後關閉",
				"jp": "{&0}後に閉じます",
				"id": "Tutup setelah {&0}",
				"hi": "{&0} के बाद बंद करें",
				"pt": "Fechar depois de {&0}",
				"es": "Cerrar después de {&0}",
				"ru": "Закрыть после {&0}",
				"ar": "إغلاق بعد {&0}",
				"ms": "Tutup selepas {&0}",
				"my": "{&0} ပြီးနောက် ပိတ်ရန်",
				"th": "ปิดหลังจาก {&0}",
				"vi": "Đóng sau {&0}"
			},
			"fullTips": {
				"en": "The game will be closed for maintenance after {&0}. Maintenance will be soon, so stay tuned!",
				"zh": "游戏将在{&0}后关闭维护，维护很快，敬请期待！",
				"zhf": "遊戲將在{&0}後關閉維護，維護很快，敬請期待！",
				"jp": "ゲームは {&0} 以降メンテナンスのため停止されます。メンテナンスは間もなく完了しますので、今しばらくお待ちください。",
				"id": "Game akan ditutup untuk pemeliharaan setelah {&0}. Pemeliharaan akan segera dilakukan, jadi pantau terus!",
				"hi": "खेल को रखरखाव के लिए {&0} के बाद बंद कर दिया जाएगा। रखरखाव जल्द ही होगा, इसलिए बने रहें!",
				"pt": "O jogo será fechado para manutenção após {&0}. A manutenção será em breve, fique ligado!",
				"es": "El juego se cerrará por mantenimiento después del {&0}. El mantenimiento será pronto, ¡así que estad atentos!",
				"ru": "Игра будет закрыта на техническое обслуживание после {&0}. Техническое обслуживание будет скоро, так что следите за обновлениями!",
				"ar": "سيتم إغلاق اللعبة للصيانة بعد {&0}. الصيانة ستكون قريبة، فتابعنا!",
				"ms": "Permainan akan ditutup untuk penyelenggaraan selepas {&0}. Penyelenggaraan akan dibuat tidak lama lagi, jadi nantikan!",
				"my": "{&0} ပြီးနောက် ပြုပြင်ထိန်းသိမ်းမှုအတွက် ဂိမ်းကို ပိတ်လိုက်ပါမည်။ ပြုပြင်ထိန်းသိမ်းမှု မကြာမီပြုလုပ်တော့မည်ဖြစ်သောကြောင့် စောင့်မျှော်ကြည့်ရှုလိုက်ပါ။",
				"th": "เกมจะถูกปิดเพื่อการบำรุงรักษาหลังจาก {&0} การบำรุงรักษาจะมีขึ้นในเร็วๆ นี้ ดังนั้นโปรดคอยติดตาม!",
				"vi": "Trò chơi sẽ đóng cửa để bảo trì sau {&0}. Việc bảo trì sẽ sớm diễn ra, vì vậy hãy chú ý theo dõi!"
			}
		};
		this._langData.setJsonLangData(json);
	}

	private resetDialog() {
		this.title.string = this._langData.getString("msgtitle");
		this.tipsOk.string = this._langData.getString("confirm");
		const str = this._langData.getString("fullTips", this.secStr);
		this.messageFull.string = str;
	}

	private resetTips() {
		const str = this._langData.getString("shortTips", this.secStr);
		this.messageShort.string = str;
	}

}
